package edu.scau.mis.controller.admin;

import edu.scau.mis.core.controller.ResultEntity;
import edu.scau.mis.sys.entity.SysAdmin;
import edu.scau.mis.sys.entity.VerifyCode;
import edu.scau.mis.sys.security.service.TokenService;
import edu.scau.mis.sys.service.*;
import edu.scau.mis.sys.vo.LoginUserVo;
import edu.scau.mis.sys.vo.SysAdminVo;
import edu.scau.mis.sys.vo.SysPermissionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/admin")
public class AuthenticationController {
    @Autowired
    AuthenticationService authenticationService;

    @Autowired
    VerifyCodeGenService verifyCodeGenService;

    @Autowired
    SysPermissionService sysPermissionService;

    @Autowired
    SysAdminService sysAdminService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @Autowired
    SysRoleService sysRoleService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @GetMapping("/input-code")
    public ResultEntity getInputCode(@RequestParam("width") int width,
                                     @RequestParam("height") int height){
        VerifyCode verifyCode = verifyCodeGenService.generate(width, height);
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("inputCode", verifyCode.getCode());
        responseData.put("inputCodePhoto", verifyCode.getPhotoUrl());
        return ResultEntity.success("操作成功", responseData);
    }

    @PostMapping("/login")
    public ResultEntity login(@RequestBody LoginUserVo loginUserVo){
        String token = authenticationService.login(loginUserVo.getUsername(), loginUserVo.getPassword());
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("token", token);
        SysAdmin sysAdmin = sysAdminService.queryByUsername(loginUserVo.getUsername());
        responseData.put("username", sysAdmin.getUsername());
        responseData.put("name", sysAdmin.getName());
        responseData.put("avatarUrl", sysAdmin.getAvatarUrl());
        return ResultEntity.success("登录成功", responseData);
    }

    @GetMapping("/permission")
    @PreAuthorize("@ex.hasAuthority('admin', 'normal', 'manage', 'waiter')")
    public ResultEntity permission(HttpServletRequest request){
        //从请求头获取token
        String token = request.getHeader("Authorization");

        //获取用户名
        String username = Objects.requireNonNull(TokenService.parseToken(token)).getSubject();

        List<SysPermissionVo> sysPermissionVoList = sysPermissionService.queryPermissionByName(username);
        HashMap<String,Object> responseData = new HashMap<>();
        responseData.put("permissionList", sysPermissionVoList);
        return ResultEntity.success("操作成功", responseData);
    }

    @PutMapping("/password")
    @PreAuthorize("@ex.hasAuthority('admin', 'normal', 'manage', 'waiter')")
    public ResultEntity changePassword(@RequestBody Map<String, Object> map,
                                       HttpServletRequest request){
        //从请求头获取token
        String token = request.getHeader("Authorization");
        //获取用户名
        String username = Objects.requireNonNull(TokenService.parseToken(token)).getSubject();
        //获取用户
        SysAdmin sysAdmin = sysAdminService.queryByUsername(username);

        //获取map信息
        String oldPassword = (String)map.get("oldPassword");
        String password = (String)map.get("password");
        String confirmPassword = (String)map.get("confirmPassword");

        if(!password.equals(confirmPassword)){
            return ResultEntity.error("两次密码输入不一致");
        }

        if(!passwordEncoder.matches(oldPassword, sysAdmin.getPassword())){
            return ResultEntity.error("原密码输入有误");
        }

        sysAdminService.updateByPassword(sysAdmin.getId(), passwordEncoder.encode(password));

        return ResultEntity.success("修改成功");
    }

    @PostMapping("/userinfo")
    @PreAuthorize("@ex.hasAuthority('admin')")
    public ResultEntity addUser(@RequestBody SysAdminVo sysAdminVo){
        if(sysAdminService.queryByUsername(sysAdminVo.getUsername()) != null){
            return ResultEntity.error("该账户已存在");
        }

        //插入角色
        sysAdminService.insertAdmin(sysAdminVo);

        //插入用户角色
        List<String> roles = sysAdminVo.getRoles();
        for (int i = 0; i < roles.size(); i++) {
            sysUserRoleService.insertRoleUser(sysAdminVo.getId(), sysRoleService.queryByName(roles.get(i)).getId());
        }
        return ResultEntity.success("操作成功");
    }

    @PutMapping("/admin-userinfo")
    @PreAuthorize("@ex.hasAuthority('admin')")
    public ResultEntity updateUserWithAdmin(@RequestBody SysAdminVo sysAdminVo) {
        if (sysAdminService.queryByUsername(sysAdminVo.getUsername()) != null) {
            return ResultEntity.error("该用户不存在");
        }

        //修改角色信息
        sysAdminService.updateSysAdminWithSuper(sysAdminVo);

        //修改用户角色
        List<String> roles = sysAdminVo.getRoles();
        for (int i = 0; i < roles.size(); i++) {
            //先删除，再新增，不能直接修改，因为修改也可能是用户角色可能由2个变成1个
            sysUserRoleService.deleteByUserId(sysAdminService.queryByUsername(sysAdminVo.getUsername()).getId());

            sysUserRoleService.insertRoleUser(sysAdminVo.getId(), sysRoleService.queryByName(roles.get(i)).getId());
        }
        return ResultEntity.success("操作成功");
    }

    @PutMapping("/userinfo")
    @PreAuthorize("@ex.hasAuthority('normal', 'manage', 'waiter')")
    public ResultEntity updateUser(@RequestBody SysAdminVo sysAdminVo) {
        if (sysAdminService.queryByUsername(sysAdminVo.getUsername()) != null) {
            return ResultEntity.error("该用户不存在");
        }

        //修改角色信息
        sysAdminService.updateSysAdminWithSuper(sysAdminVo);

        return ResultEntity.success("操作成功");
    }
}
